﻿@inherits Blazor.SysRoleForm

<div class="role" style="display:flex;">
    <div style="width:400px;padding-right:20px;">
        <DataForm Model="Model" />
    </div>
    <div style="width:260px;">
        <div>模块</div>
        <Tree TItem="Known.MenuItem" ShowIcon Checkable
              DataSource="Model.Data.Menus" OnClick="OnTreeClick" OnCheck="OnTreeCheck"
              DefaultCheckedKeys="Model.Data.MenuIds.ToArray()"
              DisabledExpression="x => !x.DataItem.Enabled || Model.IsView"
              KeyExpression="x => x.DataItem.Id"
              TitleExpression="x => x.DataItem.Name"
              IconExpression="x => x.DataItem.Icon"
              ChildrenExpression="x => x.DataItem.Children"
              IsLeafExpression="x => x.DataItem.Children?.Count == 0" />
    </div>
    <div style="background-color:#f5f5f5;width:160px;">
        <div>
            <span>按钮</span>
            @* <Checkbox Disabled="Model.IsView" Indeterminate="indButton" CheckedChanged="ButtonAllChanged" /> *@
        </div>
        <CheckboxGroup Disabled="CheckDisabled" Options="allButtons" ValueChanged="OnButtonChanged" />
    </div>
    <div style="background-color:#f1f1f1;width:160px;">
        <div>
            <span>栏位</span>
            @* <Checkbox Disabled="Model.IsView" Indeterminate="indColumn" CheckedChanged="ColumnAllChanged" /> *@
        </div>
        <CheckboxGroup Disabled="CheckDisabled" Options="allColumns" ValueChanged="OnColumnChanged" />
    </div>
</div>

<style>
     .role .ant-checkbox-group {display:flex;flex-direction:column;padding:5px;}
</style>

 @code {
    private TreeNode<Known.MenuItem> current;
    private bool CheckDisabled => Model.IsView || current == null || !current.Checked;

    private void OnTreeClick(TreeEventArgs<Known.MenuItem> e) => SelectNode(e.Node);

    private void OnTreeCheck(TreeEventArgs<Known.MenuItem> e)
    {
        SelectNode(e.Node);

        var btnItems = e.Node.Checked ? allButtons.Select(o => o.Value).ToArray() : null;
        var colItems = e.Node.Checked ? allColumns.Select(o => o.Value).ToArray() : null;
        allButtons.ForEach(o => o.Checked = e.Node.Checked);
        allColumns.ForEach(o => o.Checked = e.Node.Checked);
        OnButtonChanged(btnItems);
        OnColumnChanged(colItems);

        Model.Data.MenuIds.Remove(e.Node.DataItem.Id);
        if (e.Node.Checked)
            Model.Data.MenuIds.Add(e.Node.DataItem.Id);
    }

    private CheckboxOption[] allButtons = [];
    // private bool indButton;
    // private bool checkButton;
    // private void ButtonAllChanged()
    // {
    //     checkButton = !checkButton;
    //     allButtons.ForEach(o => o.Checked = checkButton);
    // }

    private void OnButtonChanged(string[] items)
    {
        //indButton = Indeterminate(allButtons);
        Model.Data.MenuIds.RemoveAll(m => m.StartsWith($"b_{current.DataItem.Id}"));
        if (items != null && items.Length > 0)
            Model.Data.MenuIds.AddRange(items);
    }

    private CheckboxOption[] allColumns = [];
    // private bool indColumn;
    // private bool checkColumn;
    // private void ColumnAllChanged()
    // {
    //     checkColumn = !checkColumn;
    //     allColumns.ForEach(o => o.Checked = checkColumn);
    // }

    private void OnColumnChanged(string[] items)
    {
        //indColumn = Indeterminate(allColumns);
        Model.Data.MenuIds.RemoveAll(m => m.StartsWith($"c_{current.DataItem.Id}"));
        if (items != null && items.Length > 0)
            Model.Data.MenuIds.AddRange(items);
    }

    private void SelectNode(TreeNode<Known.MenuItem> node)
    {
        current = node;
        allButtons = current.DataItem.GetAllActions().ToOptions(o =>
        {
            o.Checked = Model.Data.MenuIds.Contains(o.Value);
            o.Disabled = Model.IsView;
        });

        allColumns = current.DataItem.GetAllColumns().ToOptions(o =>
        {
            o.Checked = Model.Data.MenuIds.Contains(o.Value);
            o.Disabled = Model.IsView;
        });
    }

    // private bool Indeterminate(CheckboxOption[] options)
    // {
    //     return options.Count(o => o.Checked) > 0 && options.Count(o => o.Checked) < options.Count();
    // }
}